home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
doom
/
quake.zip
/
PERFEC_1.ZIP
/
HOOK.QC
< prev
next >
Wrap
Text File
|
1997-04-19
|
11KB
|
338 lines
//====================================================================
//
// BASED ON: HOOK 2.2 & 3.0b3 by: Perecli Manole AKA Bort
//
// MODIFIED BY: Enrico Del Fante (TbEnr)
//
//====================================================================
// Aside from this new file, the following are the modifications
// done to id's original source files:
//--------------------------------------------------------------------
// File: Progs.src
// Location: before the "weapons.qc" line
// Added: hook.qc
//--------------------------------------------------------------------
// File: World.qc
// Procedure: worldspawn
// Location: after line "precache_model ("progs/s_spike.mdl");"
// Added: precache_model ("progs/star.mdl");
// precache_model ("progs/bit.mdl");
//--------------------------------------------------------------------
// File: Weapons.qc
// Procedure: W_Precache
// Location: end of procedure
// Added: precache_sound ("shambler/smack.wav");
// precache_sound ("blob/land1.wav");
// precache_sound ("hook/retract.wav");
//--------------------------------------------------------------------
// File: Weapons.qc
// Procedure: W_WeaponFrame
// Location: in the begining of procedure
// Added: CheckGrapHook ();
//--------------------------------------------------------------------
// File: Weapons.qc
// Procedure: W_WeaponFrame
// Location: after line "if (time < self.attack_finished)" before
// line "return;"
// Added: {
// self.impulse=0;
// (leave line "return;")
// }
//--------------------------------------------------------------------
// File: Defs.qc
// Declaration group: player only fields
// Location: after line ".float pain_finished;"
// Added: .float hook;
//--------------------------------------------------------------------
void(vector org, vector vel, float damage) SpawnBlood; // prototype
float () crandom; // prototype
float HOOK_OUT = 1; // is hook currently extended? (bit flag)
float HOOK_ON = 2; // is ACTIVE_HOOK impulse on? (bit flag)
float HOOK_PULL = 4;
float HOOK_CANC = 8;
float ACTIVATE_HOOK = 98; // impulse constant
float TERMINATE_HOOK = 97; // impulse constant
float MAX_CHAIN_LEN = 800;
float (vector from, vector onto) Dot =
{
return from_x * onto_x + from_y * onto_y + from_z * onto_z;
};
/*
//--------------------------------------------------------------------
// Disolves chain
//--------------------------------------------------------------------
void (entity Head) DisolveChain =
{
local entity link;
link = Head.goalentity;
while (link != world)
{
Head = link.goalentity;
remove (link);
link = Head;
}
};
*/
//--------------------------------------------------------------------
// Updated calculation of link positions
//--------------------------------------------------------------------
void () LinkPos =
{
setorigin (self, self.owner.origin + ((self.enemy.origin + '0 0 16') - self.owner.origin) * self.weapon);
self.nextthink = time + 0.01;
};
//--------------------------------------------------------------------
// Creates chain
//--------------------------------------------------------------------
entity (entity head, entity tail, float num) CreateChain =
{
local entity link, prevlink;
local float linknum;
linknum = num;
num = num + 1;
prevlink = world;
while (linknum > 0)
{
link = spawn();
link.goalentity = prevlink;
prevlink = link;
link.owner = head;
link.enemy = tail;
link.weapon = linknum / num;
link.movetype = MOVETYPE_NOCLIP;
link.solid = SOLID_NOT;
link.angles_z = 51 * linknum;
link.angles_y = 41 * linknum;
link.angles_x = 31 * linknum;
link.avelocity = '310 410 510';
setmodel (link, "progs/bit.mdl");
setsize (link, '0 0 0', '0 0 0');
setorigin (link, head.origin + ((tail.origin + '0 0 16') - head.origin) * link.weapon);
link.nextthink = time + 0.01;
link.think = LinkPos;
linknum = linknum - 1;
}
return link;
};
//--------------------------------------------------------------------
// Removes star and detaches player
//--------------------------------------------------------------------
void () HookVanish =
{
// removes flag of hook instance being present
self.owner.hook = self.owner.hook - (self.owner.hook & HOOK_OUT);
self.owner.hook = self.owner.hook - (self.owner.hook & HOOK_CANC);
self.owner.hook = self.owner.hook - (self.owner.hook & HOOK_PULL);
local entity linkptr;
local entity nextptr;
// removes chain
linkptr = self.goalentity;
while (linkptr != world)
{
nextptr = linkptr.goalentity;
remove (linkptr);
linkptr = nextptr;
}
sound (self.owner, CHAN_AUTO, "hook/retract.wav", 1, ATTN_NORM);
remove (self);
};
//--------------------------------------------------------------------
// Hook pulls player function
//--------------------------------------------------------------------
void () HookPull =
{
if ((self.owner.hook & HOOK_CANC) == HOOK_CANC)
{
HookVanish();
return;
}
local vector vel, spray, velpart;
local float v,f1,i1,i2;
local vector chainvec; // chain vector
local float chainlength; // length of extended chain
if ((self.owner.teleport_time > time) ||
(self.owner.deadflag) || // if player dies
(self.enemy.solid == SOLID_NOT) ) // if target dies
{
HookVanish();
return;
}
if (self.enemy.takedamage)
T_Damage (self.enemy, self, self.owner, 3);
if (self.enemy.solid == SOLID_SLIDEBOX)
{
sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM);
spray_x = 100 * crandom();
spray_y = 100 * crandom();
spray_z = 100 * crandom() + 50;
SpawnBlood (self.origin, spray, 20);
setorigin (self, self.enemy.origin + self.enemy.mins + self.enemy.size * 0.5);
}
self.velocity = self.enemy.velocity;
chainvec = self.origin - (self.owner.origin + '0 0 16');
chainlength = vlen (chainvec);
if ((self.owner.hook & HOOK_ON) == HOOK_ON) {
vel = self.origin - (self.owner.origin + '0 0 16');
v = vlen (vel);
if (v <= 100)
vel = normalize(vel) * v * 7;
if ( v > 100 )
vel = normalize(vel) * 700;
self.owner.velocity = vel;
self.armorvalue=chainlength;
}
else
{
if (chainlength > self.armorvalue)
{
f1 = (chainlength - self.armorvalue) * 3;
// dampens player's velocity moving away from hook
i1 = Dot(self.owner.velocity,chainvec);
i2 = Dot(chainvec,chainvec);
velpart = chainvec * (i1 / i2);
self.owner.velocity = self.owner.velocity - velpart;
i1 = vlen (velpart);
if (i1 > 600)
sound (self.owner, CHAN_AUTO, "player/land2.wav", 1, ATTN_NORM);
}
else
f1 = 0;
// applys forces to players velocity
self.owner.velocity = self.owner.velocity + normalize(chainvec) * f1;
}
self.nextthink = time + 0.1;
};
//--------------------------------------------------------------------
// Star's touch function
//--------------------------------------------------------------------
void() T_ChainTouch =
{
if (other.takedamage)
T_Damage (other, self, self.owner, 10 );
if (other.solid == SOLID_SLIDEBOX)
{
sound (self, CHAN_WEAPON, "shambler/smack.wav", 1, ATTN_NORM);
SpawnBlood (self.origin, self.velocity, 10);
setorigin (self, other.origin + other.mins + other.size * 0.5);
}
else
{
sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
self.avelocity = '0 0 0';
}
self.velocity = other.velocity;
if ((self.owner.hook & HOOK_ON) == HOOK_ON)
self.owner.hook=self.owner.hook | HOOK_PULL;
else self.owner.hook=self.owner.hook - (self.owner.hook & HOOK_PULL);
self.enemy = other;
self.nextthink = time + 0.1;
self.think = HookPull;
self.touch = SUB_Null;
};
void() LaunchHook =
{
local vector chainvec; // chain vector
local float chainlength; // length of extended chain
chainvec = self.origin - (self.owner.origin + '0 0 16');
chainlength = vlen (chainvec);
// armorvalue is used to hold current length of chain
self.armorvalue = chainlength;
if (chainlength > MAX_CHAIN_LEN)
{
HookVanish();
return;
}
self.nextthink = time + 0.1;
};
//--------------------------------------------------------------------
// Shoots star
//--------------------------------------------------------------------
void(entity myself) W_FireChain =
{
local entity star;
star = spawn ();
star.owner = myself;
star.movetype = MOVETYPE_FLY;
star.solid = SOLID_BBOX;
setmodel (star, "progs/star.mdl");
setsize (star, '0 0 0', '0 0 0');
makevectors (myself.v_angle);
setorigin (star, myself.origin + (v_forward*16) + '0 0 16' );
star.velocity = v_forward*1000;
star.angles = vectoangles(star.velocity);
star.avelocity = '0 0 600';
sound (myself, CHAN_AUTO, "weapons/ax1.wav", 1, ATTN_NORM);
star.touch = T_ChainTouch;
star.nextthink = time + 0.1;
star.think = LaunchHook;
star.goalentity = CreateChain (star, myself, 8);
};
//--------------------------------------------------------------------
// Checks impulse
//--------------------------------------------------------------------
void() CheckGrapHook =
{
if (((self.hook & HOOK_OUT) != HOOK_OUT) && (self.impulse == ACTIVATE_HOOK))
{
// flags that one instance of hook is spawned
self.hook = self.hook | HOOK_OUT;
// flags last activated hook impulse as being ON
self.hook = self.hook | HOOK_ON;
W_FireChain (self);
return;
}
if (((self.hook & HOOK_ON) != HOOK_ON) && (self.impulse == ACTIVATE_HOOK))
{
if (((self.hook & HOOK_OUT) == HOOK_OUT) && ((self.hook & HOOK_PULL) != HOOK_PULL))
self.hook=self.hook | HOOK_CANC;
self.hook = self.hook | HOOK_ON;
return;
}
if (((self.hook & HOOK_OUT) == HOOK_OUT) && (self.impulse == TERMINATE_HOOK))
{
if ((self.hook & HOOK_PULL) == HOOK_PULL)
self.hook = self.hook | HOOK_CANC;
// flags last activated hook impulse as being OFF
self.hook = self.hook - (self.hook & HOOK_ON);
return;
}
};